/** @format */

import { isObject, def } from '../util/index.js';
import { arrayMethods } from './array.js';

class Observer {
  constructor(value) {
    // 给对象value增加一个隐藏属性
    def(value, '__ob__', this);
    // value.__ob__ = this;  // 给每一个监控过的对象增加一个__ob__属性
    if (Array.isArray(value)) {
      // 如果是数组的话并不会对索引进行观测，因为会导致性能问题

      // 拦截数组操作方法
      value.__proto__ = arrayMethods;
      this.observerArray(value);
    } else {
      this.walk(value);
    }
  }

  observerArray(value) {
    for (let i = 0; i < value.length; i++) {
      observe(value[i]);
    }
  }

  walk(data) {
    let keys = Object.keys(data); // [name,age,address]
    // 如果这个data 不可配置 直接reurn
    keys.forEach((key) => {
      defineReactive(data, key, data[key]);
    });
  }
}

function defineReactive(data, key, value) {
  observe(value); // 递归实现深度检测
  Object.defineProperty(data, key, {
    configurable: true,
    enumerable: true,
    get() {
      //  获取值的时候做一些操作
      return value;
    },
    set(newValue) {
      // 也可以做一些操作
      if (newValue === value) return;
      observe(newValue); // 继续劫持用户设置的值，因为有可能用户设置的值是一个对象
      value = newValue;
    },
  });
}

//  把data中的数据，都Object.defineProperty重新定义
export function observe(data) {
  let isObj = isObject(data);
  if (!isObj) return;

  console.log(data);
  return new Observer(data);
}
